package com.syq.shiro;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.syq.mapper.DtsAdminMapper;
import com.syq.mapper.DtsPermissionMapper;
import com.syq.mapper.DtsRoleMapper;
import com.syq.pojo.DtsAdmin;
import com.syq.pojo.DtsPermission;
import com.syq.pojo.DtsRole;
import com.syq.util.bcrypt.BCryptPasswordEncoder;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @ClassName: AdminAuthorizingRealm
 * @Description: TODO
 * @Create by: syq
 * @Date: 2022/7/21 15:03
 */


public class AdminAuthorizingRealm extends AuthorizingRealm {

    @Autowired
    private DtsAdminMapper dtsAdminMapper;

    @Autowired
    private DtsPermissionMapper dtsPermissionMapper;

    @Autowired
    private DtsRoleMapper dtsRoleMapper;

    //认证
    @Transactional
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken= (UsernamePasswordToken) token;
        String username = usernamePasswordToken.getUsername();
        String password = new String(usernamePasswordToken.getPassword());

        QueryWrapper<DtsAdmin> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("username",username);

        DtsAdmin dtsAdmin = dtsAdminMapper.selectOne(queryWrapper);

        if (null==dtsAdmin){
            throw new UnknownAccountException();
        }

        if (!new BCryptPasswordEncoder().matches(password,dtsAdmin.getPassword())){
            throw new IncorrectCredentialsException();
        }
        if(dtsAdmin.getDeleted()){
           throw  new LockedAccountException();
        }

        return new SimpleAuthenticationInfo(dtsAdmin,password,this.getName());
    }

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        DtsAdmin dtsAdmin = (DtsAdmin) principals.getPrimaryPrincipal();
        Integer[] roleIds = dtsAdmin.getRoleIds();
        List<DtsRole> dtsRoleList = dtsRoleMapper.selectBatchIds(Arrays.asList(roleIds));
        Set<String> roleNames = dtsRoleList.stream().map(DtsRole::getName).collect(Collectors.toSet());

        List<DtsPermission> dtsPermissionList = dtsPermissionMapper.selectList(new QueryWrapper<DtsPermission>()
                .in("role_id", roleIds));
        Set<String> permissionList = dtsPermissionList.stream().map(DtsPermission::getPermission).collect(Collectors.toSet());
        SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(roleNames);
        authorizationInfo.setStringPermissions(permissionList);
        return authorizationInfo;
    }
}
